ホームに戻る
出典 :
ListBox クラス (System.Windows.Controls) | Microsoft Learn C#WPFの道#21!ListBoxの書き方と使い方を解りやすく解説 - ピーコックアンダーソン WPFのListBox.SelectedItems(複数選択)を取り出すのが意外と大変だった #C# - Qiita WPFで使いまわしができる「ListBox.SelectedItemsを取得するメソッド」 #C# - Qiita よしいずの雑記帳 WPFのListBoxのSelectedItemsにデータバインディングする例 [WPF] ListBoxで選択可能な数に上限を設定する #C# - Qiita
関連 :
ComboBox [.NET]コレクション [.NET]Dictionary(連想配列) ReactiveProperty
目次 :

ListBox (System.Windows.Controls)

コレクションの一覧を表示し、そのうちの一つまたは複数を選択できるコントロール。 詳細はリファレンスを参照。

実装例

XAML
<Window x:Class="WPF021.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local="clr-namespace:WPF021" mc:Ignorable="d" Title="MainWindow" Height="300" Width="300"> <Grid> <!-- ListBox --> <ListBox x:Name="MyListBox" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="10" Width="260" Height="180"> <ListBox.ItemTemplate> <DataTemplate> <StackPanel Orientation="Horizontal"> <!-- コレクション要素の FileName にバインド --> <Image Source="{Binding FileName}" Width="50" Height="50" Margin="10"/> <!-- コレクション要素の Name にバインド --> <TextBlock Text="{Binding Name}" Margin="10"/> </StackPanel> </DataTemplate> </ListBox.ItemTemplate> </ListBox> </Grid> </Window>
CS
using System.Collections.ObjectModel; using System.Windows; using System.Windows.Controls; namespace WPF021 { /// /// MainWindow.xaml の相互作用ロジック /// public partial class MainWindow : Window { // ListBox の ItemsSource として用いる ObservableCollection private ObservableCollection _persons = new ObservableCollection(); // コンストラクタ public MainWindow() { InitializeComponent(); // ListBox の項目を追加、バインディング _persons.Add(new Person("Images/A.jpeg", "Shinichi ONO")); _persons.Add(new Person("Images/B.jpeg", "Jyunta INAMOTO")); _persons.Add(new Person("Images/C.jpeg", "Naotaro TAKAHARA")); MyListBox.ItemsSource = _persons; } } // 人物データ // ( ListBox の項目) public sealed class Person { public Person(string fileName, string name) { FileName = fileName; Name = name; } public string FileName { get; set; } public string Name { get; set; } } }
画面表示
画像
解説
上記は Person クラスを項目にとる ListBox の実装例である。 ListBox.ItemTemplate およびその子要素の DataTemplate で、ListBox 表示内容の詳細を規定している。 ListBox の各行には画像とテキストを表示しており、画像のパスを Person.FileName 、テキストを Person.Name にバインドしている。 ListBox の項目一覧は ItemsSource で規定され、ここでは Person からなる ObservableCollection を用いている。 ( ObservableCollection を用いているのは、コレクションに変更があった場合にターゲットである ListBox (の ItemsSource )に通知を発行するため。 これにより、ターゲットをソースに連動して変更させられる。ReactiveProperty で代用可能。)

ItemsSource に指定できるデータ

ListBox の項目を司る ItemsSource は System.Collections.IEnumerable 型のプロパティとして宣言されており、 インタフェース IEnumerable を実装する大半のコレクションを値としてとることができる。 System.Collection.Generic.List<T> や配列 ( T[] : System.Array )が一般的。

Dictionary を ItemsSource に指定する

ItemsSource には System.Collection.Generic.Dictionary<TKey, TValue> も使用できる。 (キーのみの集合 Dictionary.KeyCollection 、値のみの集合 Dictionary.ValueCollection も同様に使用可能。) Dictionary の各項目は KeyValuePair<TKey, TValue> であるため、 キーにアクセスするには KeyValuePair.Key 、値にアクセスするには KeyValuePair.Value のプロパティをそれぞれ用いる。

表示と値に異なるメンバを用いる

ItemsSource に指定した項目の中から、ListBox 上の表示に用いるものと、値として取得するものを別にすることができる。
DisplayMemberPath
表示に使用するメンバ名。
SelectedValuePath
値として使用するメンバ名。
例えば Dictionary<string, string> を ItemsSource に指定し、 DisplayMemberPath = "Key" 、SelectedValuePath = "Value" とすると、ListBox には Dictionary のキーを列挙し、 SelectedValue で取得する値は Dictionary の値、とすることができる。

選択された項目の取得

SelectedItem
型は object 。最初に選択された項目を取得する。項目が選択されていない場合は null となる。
値(選択項目)の設定も可能。
SelectedItems
型は IList 。選択された項目をすべて取得する。
SelectedValue
型は object 。SelectedItem で取得した object のうち、SelectedValuePath で指定されたメンバを取得する。
いずれも元の型をラップするため、内容を取り出すにはキャストが必要。

SelectedItems へのデータバインディング

ListBox.SelectedItems をターゲットとしたデータバインディングは通常では行えない。 ビヘイビアを作成することでバインディングが可能となる。詳細は出典元を参照。

選択方法の指定

SelectionMode プロパティに値を設定することで、選択方法を変更することができる。設定できる値は以下の通り。
SelectionMode.Single
単一の項目のみを選択可能とする。
SelectionMode.Multiple
任意の複数の項目を選択可能とする。マウスクリックにより選択・非選択を切り替える。
SelectionMode.Extended
任意の複数の項目を選択可能とする。Shiftキーを押しながらクリックで連続した行を、Ctrlキーを押しながらクリックで離れた行を選択できる。

同時選択可能な項目数に上限を設ける

ListBox のプロパティには選択上限は存在しないため、同時に選択されている項目数をコードで監視する必要がある。 出典元を参照。

スクロールバーの表示について注意が必要な点

※ この単元は正確でない可能性があります。 ListBox が内容を表示しきれない場合、実装によってはスクロールバーが表示されないことがある。 画像 上図の左側は、ListBox の Height を Auto に、MaxHeight に特定の値を設定しているが、高さが MaxHeight に達しても垂直スクロールバーが表示されない。 これは、親要素( StackPanel )の Height が Auto になっていることによる。 スクロールバーを表示させるには、親要素の Height を明確に指定し、かつ ListBox の VerticalAlignment を Stretch (デフォルト)とすればよい。

ComboBox との違い

ComboBox とは以下のような差異がある。ドロップダウンリストを作成する際は通常、ComboBox を用いる。
項目表示 直接入力
ListBox 常にすべての項目 選択された項目のみ(ドロップダウンリスト展開中を除く)
ListBox 不可 可能